Skip to content

Layer 0 amendment: unified decomposition redesign spec (Phase R + T + B2)#74

Merged
StarGazerM merged 2 commits into
design/redesign-packagefrom
feat/phase-decomposition-redesign-spec
May 19, 2026
Merged

Layer 0 amendment: unified decomposition redesign spec (Phase R + T + B2)#74
StarGazerM merged 2 commits into
design/redesign-packagefrom
feat/phase-decomposition-redesign-spec

Conversation

@StarGazerM

Copy link
Copy Markdown
Collaborator

Summary

Doc-only — 1238-line architectural spec that supersedes the piecemeal A3 cleanup with a unified attack on three decomposition problems under ONE ACID test.

ACID test (the new load-bearing invariant):

For ANY new algorithm OR new backend target, the addition must be purely additive — zero edits to existing source files. Contribution = plugin (new typed ops + @lowering rules + @register_render registrations + entry-point declaration).

Today the redesign satisfies this for ~one slice of one target (per-MIR-op kernel-body @lowering on CUDA). It does NOT satisfy it for three other concerns.

The three problems addressed

  1. Phase R — Runner monolith: orchestrator + complete_runner + runner = 2800 LOC of imperative CUDA-shaped scheduling. Becomes RIR (runner IR) + per-MIR-op @lowering rules + @register_render handlers.
  2. Phase T — Target leakage into IR: IIR ops carry CUDA C++ shape (SaTiledCartesian2D op docstring IS the C++ template — it doesn't just encode the shape, it IS the shape). LoweringCtx holds ~15 CUDA-render scratch fields. Split into target-agnostic LowerCtx (5 fields, F3-pinned) + per-target CudaRenderCtx. Rename CUDA-shaped IIR ops to semantic names.
  3. Phase B2 — Target monopolization: compile_kernel_body(ep, target='cuda') accepts the param but the rest of the pipeline hard-wires CUDA. Compiler.run(prog, target='cuda') + multi-target targets=['cuda', 'cpu_tbb']. Plugin discovery splits into [srdatalog.dialects] (data) + [srdatalog.targets] (render). R3 verify_renderability becomes per-target.

Biggest surprises uncovered during diagnosis

  1. ep_has_X(...) helpers are the bool-field anti-pattern reskinned. The parked A3-1/2/3 branches replace if ep.dedup_hash: with if ep_has_pragma(ep, DedupHash): — same imperative branch, different key. Spec § 8.3 marks them as net-negative work post-redesign; Phase R deletes both bool reads AND helper reads in one shot.
  2. complete_runner.py:37 literal cross-tree side-effect import to trigger CUDA plugin registration. Runner knows a specific data dialect by name. Worse coupling than the brief described.
  3. LoweringCtx is more entangled than expected — actual count is 9 CUDA-identifier fields + 5 pragma-scratch flags (15 total), not the 5 listed in the brief. Plus legacy CodeGenContext has 35+ fields.
  4. SaTiledCartesian2D has 20 fields and the op docstring IS the literal CUDA C++ template text at ops.py:196-232. Not "encodes CUDA shape" — IS the CUDA shape rendered into the type system.
  5. view_counts_for_specs is consumed by EmitViewDeclsShim in the supposedly-target-agnostic kernel pipeline. Spec moves it into a CUDA-render-side pass.

Per-PR partition

Expanded to 35 PRs (vs estimated 20-30) to preserve per-PR byte-equivalence gating:

  • Wave R1 framework (3) → R2 per-MIR-op lowerings (8) → R3 RIR renders (8)
  • Wave T1 LoweringCtx split (2) → T2 IIR rename (5) → T3 index-plugin split (2)
  • Wave B2-1 target param (3) → B2-2 multi-target (2)
  • Cleanup (2)

Dependency that required care: T1 must precede R3 (RIR renders need per-target render-ctx); B2-1 must precede R3-8 (per-target render dispatch is what R3-8 deletes the monolith to use).

Framing tensions

  1. Phase E retroactive versioning: Wave T3 splits each built-in dialect into data + per-target render contributions. Existing external plugins (jaccard demo External plugin demo: srdatalog_jaccard (proves third-party dialects via entry-point alone) #68) don't break (single register() form continues to work), but multi-target plugins need to split. Should Phase E be versioned E1 + E2? Spec recommends yes when Wave T3 lands; defers to reviewer.
  2. D20 vs migration-period exemption: D20 (additive contract) would block 100% of the migration PRs themselves. Spec § 7 introduces GitHub-label-based exemption (feature: blocked; migration: / refactor: exempt). Procedural rather than mechanical.
  3. Phase R brings in what original A3 spec called "out of scope" (WS runner integration). The new spec absorbs that work; parked A3 PRs are abandoned in favor of unified Phase R.

Relationship to existing work

Test plan

  • sphinx -W build: clean
  • ruff check + format (CI v0.9.10): clean
  • (Doc-only; no code paths exercised)

Why this is a DRAFT

Open as draft so you can review the spec before any subsequent migration PR references it. Conversion to ready-for-review happens after you sign off on:

  • The three-phase framing
  • The 35-PR partition + ordering
  • D20 + migration-label exemption shape
  • The parked A3 work being abandoned (vs revived/finished)

🤖 Generated with Claude Code

StarGazerM and others added 2 commits May 19, 2026 12:59
Introduces docs/phase_decomposition_redesign.md as the architectural
layer above compiler_redesign.md. Frames every remaining migration PR
against ONE load-bearing invariant: the ACID test (any new
algorithm / pragma / index type / aggregation / backend target must
be purely additive — zero edits to existing source files).

Diagnoses three concrete violation classes with file:line citations
(runner monolith ~57 imperative branches across orchestrator.py +
complete_runner.py + runner.py; target leakage into IR via CUDA-shaped
op names and LoweringCtx render fields; target monopolization in
the pipeline shims and module-global plugin registry). Proposes the
three-axis fix (Phase R Runner-IR, Phase T target abstraction, Phase
B2 target parametricity), worked examples for both a new backend and
a new algorithm, and a 35-PR migration plan that's byte-equivalence-
gated on CUDA throughout. Supersedes the parked Phase A3 branches.

Wires the new doc into docs/index.md (hidden toctree) and cross-links
from docs/compiler_redesign.md per the existing F5 pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per user feedback: 35 PRs is too granular. The per-op decomposition
duplicated framework infrastructure across PRs and made rebases
noisy. Bundle by architectural concern instead:

  PR-1 (~1500 LOC) Foundation: LowerCtx split + target parametricity
                   (Wave T1 + B2-1)
  PR-2 (~2500 LOC) RIR framework + all 10 MIR→RIR lowerings
                   (Wave R1 + R2)
  PR-3 (~3500 LOC) RIR renders + delete 2820 LOC of legacy monolith
                   (Wave R3 + Cleanup C-1)
  PR-4 (~500 LOC)  IIR rename (5-8 ops, mechanical)
                   (Wave T2)
  PR-5 (~800 LOC)  Index-plugin data/render split + Phase E
                   re-versioning (Wave T3)
  PR-6 (~600 LOC)  Multi-target + D20 discipline rule
                   (Wave B2-2 + Cleanup C-2)

Each PR is one architectural change, not one mechanical op. Per-PR
work envelope is ~1500-3500 LOC, comparable to the largest Phase B
PRs that shipped successfully. Byte-equivalence on CUDA remains the
per-PR safety net throughout.

Sequencing is strictly serial — PRs each touch broad swaths of the
codebase, so parallelism would cause significant merge conflicts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@StarGazerM
StarGazerM marked this pull request as ready for review May 19, 2026 18:25
@StarGazerM
StarGazerM merged commit e538891 into design/redesign-package May 19, 2026
3 checks passed
StarGazerM added a commit that referenced this pull request May 19, 2026
…tch gaps) (#75)

User review of merged PR #74 surfaced 8 places where the proposed RIR
vocabulary still expressed operational meaning as string-tagged dispatch
or implicit list ordering, in violation of the spec's own ACID test.
This amendment fills them by promoting each concern to typed IR ops or
typed metadata: 11 typed maintenance ops (replacing one MaintenanceCall
with kind:str), typed TerminationCheck union, typed Step.deps DAG edges,
typed DeltaVariantSet + VariantOrdering, typed MultiHeadInsert +
HeadOrdering, three typed kernel-def ops (Count/Materialize/Fused
replacing KernelDef.phase:str), typed ComposabilityMeta on Pragma, and
typed ViewBinding carrier. RIR op count grows ~10 to 30; PR-2 splits to
PR-2a + PR-2b; total ledger 6 to 7 PRs. D21 discipline (no string
dispatch in renderer bodies) added. PR-1 scope unchanged.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant